#include "gamewindow.h"
#include "ui_gamewindow.h"
using std::string;
using std::ios;

GameWindow::GameWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::GameWindow)
{
    ui->setupUi(this);
    this->resize(512, 512);
    ui->LoadingLabel->hide();
    QCursor userWidgetCursor;
    ui->UserMainWidget->setCursor(userWidgetCursor);
    ui->UserMainWidget->hide();
    ui->ChapterWidget->setCursor(userWidgetCursor);
    ui->ChapterWidget->hide();
    ui->GameBase->setCursor(userWidgetCursor);
    ui->GameBase->hide();
    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(HitStartButton()));
    connect(ui->RightButton, SIGNAL(clicked()), this, SLOT(SnakeHeadTurnRight()));
    connect(ui->LeftButton, SIGNAL(clicked()), this, SLOT(SnakeHeadTurnLeft()));
    connect(ui->MainChapter, SIGNAL(clicked()), this, SLOT(ShowLevels()));
}

string readfile(string& filepath){
    std::ifstream fileStream(filepath, ios::in);
    fileStream.open(filepath);
    string content = "{}";
    std::ostringstream Co;
    Co << fileStream.rdbuf();
    content = Co.str();
    fileStream.close();
    return content;
}

void writefile(string filepath, string content){
    std::ofstream fileStream(filepath, ios::out);
    fileStream << content;
    fileStream.close();
}

bool GameWindow::LoadStatics(){
    /*
    QString ProgressFileName("progress.json");
    QFile ProgressFile(ProgressFileName);
    qDebug() << ProgressFile.open(QIODevice::ReadWrite| QFile::Text);

    if (!ProgressFile.open(QIODevice::ReadWrite| QFile::Text)){
        qDebug("Read Failed");
        return false;
    }
    qDebug() << ProgressFile.exists() << ProgressFile.isOpen();
    QByteArray ProgressBytes(ProgressFile.readAll());
    QTextStream ProgressStream(&ProgressFile);
    */
    string ProgressFileName = "progress.json";
    QString ProgressStr(readfile(ProgressFileName).c_str());

    QJsonParseError ProgressError;
    QJsonDocument ProgressJson = QJsonDocument::fromJson(ProgressStr.toUtf8(), &ProgressError);
    if (ProgressError.error != QJsonParseError::NoError){
        qDebug() << ProgressError.errorString();
        return false;
    }
    QJsonObject ProgressObject = ProgressJson.object();

    mUserName = ProgressJson["mUserName"].toString();

    Progress = ProgressJson["mProgress"].toInt();
    Progress2 = ProgressJson["mProgress2"].toInt();
    Terminal = ProgressJson["Terminal"].toInt();
    Terminal2 = ProgressJson["Terminal2"].toInt();
    this->LoadChapter();

    QJsonArray SnakeArray = ProgressJson["SnakeHeads"].toArray();
    for (QJsonValueRef obj:SnakeArray){
        vector<string> AllClothes;
        AllClothes.push_back(obj.toString().toStdString());
        SnakeHead SNK(AllClothes);
        SnakeHeads.push_back(SNK);
    }

    //if there's no name now, ask player for a new name and record it.
    if (mUserName == ""){
        this->setEnabled(false);
        bool ok = false;
        while(!ok){
            mUserName = QInputDialog::getText(this,
                                              tr("New Player"),
                                              tr("A new name to start your game!"),
                                              QLineEdit::Normal,
                                              tr("Joe Biden"), &ok);
        }
        ProgressObject["mUserName"] = mUserName;
        ProgressJson.setObject(ProgressObject);
        writefile(ProgressFileName, ProgressJson.toJson().toStdString());
        this->setEnabled(true);
    }

    return true;
}

int GameWindow::LoadChapter(){
    int LWidth = 20;
    int LHeight = 280;
    for (int i = 1; i < Progress; i++){
        for (int j = 1; j < Terminal2; j++){
            QRect LevelQGBrect(LWidth, LHeight, 130, 50);
            Level* lev = new Level(i, j, ui->ChapterWidget, ui->GameBase, LevelQGBrect, true);
            connect(lev->StartButton, SIGNAL(clicked()), ui->ChapterWidget, SLOT(hide()));
            connect(lev->StartButton, SIGNAL(clicked()), ui->GameBase, SLOT(show()));
            connect(lev->StartButton, SIGNAL(clicked()), this, SLOT(StartGame()));
            this->Levels.push_back(lev);

            LWidth += 180;
            LHeight = myrandom(200, 400);
        }
    }
    for (int k = 1; k < Progress2; k++){
        QRect LevelQGBrect(LWidth, LHeight, 130, 50);
        Level* lev = new Level(Progress, k, ui->ChapterWidget, ui->GameBase, LevelQGBrect, true);
        connect(lev->StartButton, SIGNAL(clicked()), ui->ChapterWidget, SLOT(hide()));
        connect(lev->StartButton, SIGNAL(clicked()), ui->GameBase, SLOT(show()));
        connect(lev->StartButton, SIGNAL(clicked()), this, SLOT(StartGame()));
        this->Levels.push_back(lev);
        LWidth += 180;
        LHeight = myrandom(200, 400);
    }
    QRect LevelQGBrect(LWidth, LHeight, 130, 50);
    Level* lev = new Level(Progress, Progress2, ui->ChapterWidget, ui->GameBase, LevelQGBrect, false);
    connect(lev->StartButton, SIGNAL(clicked()), ui->ChapterWidget, SLOT(hide()));
    connect(lev->StartButton, SIGNAL(clicked()), ui->GameBase, SLOT(show()));
    connect(lev->StartButton, SIGNAL(clicked()), this, SLOT(StartGame()));
    this->Levels.push_back(lev);
    return 0;
}

void GameWindow::ShowLevels(){
    /*
    int al = Levels.size();
    for (int i = 0; i < al; i++){
        Levels[i]->show();
    }*/
    ui->ChapterWidget->show();
}

bool GameWindow::ShowLoading(){
    const QSize GamingSize(800, 600);
    this->resize(GamingSize);
    this->setAutoFillBackground(true);
    this->setStyleSheet("background-color: rgb(250, 250, 250)");
    ui->LoadingLabel->show();

    if (!LoadStatics()){
        return false;
    }

    ui->LoadingLabel->hide();

    return true;
}

/*Show the user's main window*/
bool GameWindow::ShowUserMainWindow(){
    ui->UserName->setText(mUserName);

    std::stringstream cpt;
    cpt << "Chapter:" << Progress << "-" << Progress2;
    string cptstr;
    cpt >> cptstr;
    ui->MainChapter->setText(QString(cptstr.c_str()));

    ui->UserMainWidget->show();
    return false;
}

void GameWindow::HitStartButton(){
    if (!this->ShowLoading()){
        ui->LoadingLabel->setText("Load error!");
    }
    this->ShowUserMainWindow();
}

void GameWindow::SnakeHeadTurnLeft(){
    if (NowHead != 0){
        NowHead--;
    }
    else{
        return;
    }
    ui->UserSnakeHeadImage->setStyleSheet(QString(SnakeHeads[NowHead].getImage().c_str()));
}

void GameWindow::SnakeHeadTurnRight(){
    if (NowHead < int(SnakeHeads.size()) - 1){
        NowHead++;
    }
    else{
        return;
    }
    ui->UserSnakeHeadImage->setStyleSheet(QString(SnakeHeads[NowHead].getImage().c_str()));
}

void GameWindow::StartGame(){
    Game* engine = new Game(ui->GameBase, SnakeHeads[NowHead]);
    engine->startGame();
}

GameWindow::~GameWindow()
{
    delete ui;
    int LC = int(Levels.size());
    for (int i = 0; i < LC; i++){
        delete Levels[i];
    }
}
